/*
 * Do not try to compile. That is all.
 * 
 * ---Ben
 */

package server.conn.admin;

import java.io.IOException;
import java.net.Socket;
import java.sql.SQLException;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;

import server.conn.ConnectionThread;
//import server.conn.user.UserConnectionThread;
import server.user.Admin;
import server.user.BadUserException;
import server.user.User;
import server.order.Order;

public class AdminThread extends ConnectionThread {
	public static final int USERS_LIST = 101;
	public static final int USER_DETAIL = 102;
	public static final int USER_FREEZE = 103;
	public static final int USER_SET_INFO = 104;
	public static final int USER_CHANGE_PASS = 105;
	public static final int USER_CREATE = 106;
	
	public static final int ORDERS_LIST = 201;
	public static final int ORDERS_LIST_USER = 202;
	public static final int ORDER_DETAIL = 203;
	public static final int ORDER_CANCEL = 204;
	
	protected Admin user;
	
	/**
	 * Create thread to handle a connection with a admin client
	 * @param socket	Socket holding the connection to admin client
	 * @param parent	AdminConnectionController that created this thread
	 * @param group		ThreadGroup to join
	 */
	public AdminThread(Socket socket, AdminConnectionController parent, ThreadGroup group) {
		super(socket, parent, group, "AdminThread");
	}
	
	/**
	 * Check login for user
	 * @see server.conn.ConnectionThread#checkLogin()
	 */
	protected void checkLogin() {
		printLine(ConnectionThread.OK);
		try {
			String in = readLine();
			StringTokenizer strTok = new StringTokenizer(in, ConnectionThread.SPLIT);
			if (strTok.nextToken().equals(ConnectionThread.LOGIN)) {
				String username, password;
				username = strTok.nextToken();
				password = strTok.nextToken();
				
				user = new Admin(username, password);
				//user.checkAdmin();

				if (parent.checkForUserName(username)) {
					printError("Please do not login more than once.", 3);
				} else {
					checkable = true;
					doCommands();
				}
			} else {
				printError("You have to login before doing anything", 3);
			}
		} catch (IOException e) {
			printError("IOException when reading input", 2);
		} catch (NoSuchElementException e) {
			printError("Not enough arguements for login", 3);
		} catch (SQLException e) {
			printError("SQL exception in AdminThread!\n"+e.getMessage(), 2);
		} catch (BadUserException e) {
			printError(e.getMessage(), 3);
		}
	}
	
	/**
	 * Listen for commands and execute
	 * @see server.conn.ConnectionThread#checkLogin()
	 */
	protected void doCommands() {
		printLine(ConnectionThread.OK);
		working = true;
		while (working) {
			try {
				int command;

				StringTokenizer strTok = new StringTokenizer(readLine(), ConnectionThread.SPLIT);
				command = new Integer(strTok.nextToken());
				
				switch (command) {
				case EXIT:
					printLine(BYE);
					working = false;
					break;
				case USERS_LIST:
					User userlist[] = user.fetchUsers();
					printLine(userlist.length+"");
					for(User users : userlist ){
						printLine(users.getID()+ConnectionThread.SPLIT+users.getUserName()+ConnectionThread.SPLIT+users.getRealName());
					}
					printLine(OK);
					break;
				case USER_DETAIL://||USERID
					try{
						User detail = new User(new Integer(strTok.nextToken()));
						printLine(detail.toString());
						printLine(OK);
					} catch(SQLException e){
						printLine(ERROR);
					}
					break;
				case USER_FREEZE://||USERID||BOOL_UNFREEZE
					System.out.println("trying to (un)freeze user");
					try{
						User freeze = new User(new Integer(strTok.nextToken()));
						int unfreeze = new Integer(strTok.nextToken());
						freeze.freeze(unfreeze==0);
					} catch(SQLException e){
						printLine(ERROR);
					}
					printLine(OK);
					break;
				case USER_SET_INFO://||USERID||USERNAME||NAME||EMAIL||LEVERAGE
					System.out.println("trying to change user info");
					try{
						User setinfo = new User(new Integer(strTok.nextToken()));
						String username = strTok.nextToken();
						String name = strTok.nextToken();
						String email = strTok.nextToken();
						float leverage = new Float(strTok.nextToken());
						setinfo.setInfo(username,name,email,leverage);
					} catch(SQLException e){
						printLine(ERROR);
						break;
					}
					printLine(OK);
					break;
				case USER_CHANGE_PASS://||USERID||NEWPASSWORD
					try{
						User set = new User(new Integer(strTok.nextToken()));
						set.setPass(strTok.nextToken());
					} catch(SQLException e){
						printLine(ERROR);
					}
					printLine(OK);
					break;
				case USER_CREATE://||USERNAME
					printLine(ERROR+"Not possible in this version of ACE");
					break;
				case ORDERS_LIST:
					Order[] orders = user.fetchOpenOrders();
					String[] text = new String[orders.length];
					for(int i=0;i<orders.length;i++){
						text[i]=orders[i].toString();
					}
					printArray(text);
					printLine(OK);
					break;
				case ORDERS_LIST_USER://||USERID
					try{
						printArray(new User(new Integer(strTok.nextToken())).getOpenOrders());
					} catch(SQLException e){
						printLine(ERROR);
						break;
					}
					printLine(OK);
					break;
				case ORDER_DETAIL://||ORDERID
					printLine(OK);
					break;
				case ORDER_CANCEL://||ORDERID
					printLine(OK);
					break;
				default:
					printLine(ERROR+SPLIT+"Unknown command.");
					break;
				}
			} catch (IOException e) {
				printError("IO exception in Handler!", 2);
				working = false;
			} catch (NoSuchElementException e) {
				printError("Not enough arguements for requested command!", 4);
			} catch (NumberFormatException e) {
				printError("Bad arguments given!", 4);
			}
		}
	}
}
